library ieee;
use ieee.std_logic_1164.all;
use std.textio.all;
use ieee.numeric_std.all;
use work.custom_types.all;

entity testbecnch_ALU_SKL_real is
end entity testbecnch_ALU_SKL_real;

architecture behavioral of testbecnch_ALU_SKL_real is

component ALU_SKL is
port(
  Clk : in std_logic;
  Reset : in std_logic;
  A : in std_logic_vector(31 downto 0);
  B : in std_logic_vector(31 downto 0);
  Op : in std_logic_vector(3 downto 0);
  Outs : out std_logic_vector(31 downto 0)
);
end component;

constant Size    : integer := 233460;
constant clkPeriod    : time := 0.1 us;
type Operand_array is array (Size downto 0) of std_logic_vector(31 downto 0);
type OpCode_array is array (Size downto 0) of std_logic_vector(3 downto 0);
  
signal clk,reset 			: std_logic;
signal A,B,outs,expOuts 	: std_logic_vector (31 downto 0);
signal Op					: std_logic_vector (3 downto 0);


  -----------------------------------------------------------------------------
  -- Functions
  -----------------------------------------------------------------------------
  function bin ( myChar : character) return std_logic is
    variable bin : std_logic;
  begin
    case myChar is
      when '0' => bin := '0';
      when '1' => bin := '1';
      when 'x' => bin := '0';
      when others => assert (false) report "no binary character read" severity failure;
    end case;
    return bin;
  end bin;
  
  function loadOperand (fileName : string) return Operand_array is
    file objectFile : text open read_mode is fileName;
    variable memory : Operand_array;
    variable L      : line;
    variable index  : natural := 0;
    variable myChar : character;
  begin
    while not endfile(objectFile) loop
      readline(objectFile, L);
      for i in 31 downto 0 loop
        read(L, myChar);
        memory(index)(i) := bin(myChar);
      end loop;
      index := index + 1;
    end loop;
    return memory;
  end loadOperand;


  function loadOpCode (fileName : string) return OpCode_array is
    file objectFile : text open read_mode is fileName;
    variable memory : OpCode_array;
    variable L      : line;
    variable index  : natural := 0;
    variable myChar : character;
  begin
    while not endfile(objectFile) loop
      readline(objectFile, L);
      for i in 3 downto 0 loop
        read(L, myChar);
        memory(index)(i) := bin(myChar);
      end loop;
      index := index + 1;
    end loop;
    return memory;
  end loadOpCode;
  
begin
	skl_alu_real: ALU_SKL port map (clk,reset,A,B,Op,outs);
	clk_gen: process is
	begin
		clk <= '0';
		wait for clkPeriod/2;
		clk <= '1';
		wait for clkPeriod/2;
	end process clk_gen;
	
	test_sequence : process is
	variable tv_A,tv_B,tv_expectedOuts : Operand_array;
	variable tv_Op : OpCode_array;
	begin
	
	tv_A := loadOperand("/chalmers/users/dhapar/mesd/aludesign/alu/tv_real/A.tv");
	tv_B := loadOperand("/chalmers/users/dhapar/mesd/aludesign/alu/tv_real/B.tv");
	tv_expectedOuts := loadOperand("/chalmers/users/dhapar/mesd/aludesign/alu/tv_real/ExpectOut.tv");
	tv_Op := loadOpCode("/chalmers/users/dhapar/mesd/aludesign/alu/tv_real/Op.tv");
	
	-- tv_A := loadOperand("C:\data\tv\A.tv");
	-- tv_B := loadOperand("C:\data\tv\B.tv");
	-- tv_expectedOuts := loadOperand("C:\data\tv\ExpectOut.tv");
	-- tv_Op := loadOpCode("C:\data\tv\Op.tv");
	
	for i in 0 to 233450 loop	
		A 	<= tv_A(i);
		B 	<= tv_B(i);
		Op  <= tv_Op(i);
		if i > 0 then
		 expOuts <= tv_expectedOuts(i-1); 
		end if; 
		reset  <= '1';
		
		wait for clkPeriod;
		if i > 0 then
		if outs/= expOuts then 
          ASSERT false
          REPORT " ALU_RCA TC" &integer'image(i-1) &"error"
          SEVERITY failure;
        end if;
      end if;
	end loop;	
	ASSERT false
        REPORT "Tested OK"
        SEVERITY failure;
	
	end process test_sequence;
end architecture behavioral;
-----------------------------------------------------------------------------